#coding:utf8
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from pynput import keyboard
from pynput import mouse
import sys
import redis
import json,time
import copy

f = open('config.json')
j = json.load(f)
f.close()
ip = j['ip']
port1 = j['port1']
port2 = j['port2']
sec = j['sec']
scale = j.get('scale',1)
right_click_gear = True
left_right_switch = j.get('left_right_switch',True)
scale_float = j.get('scale_float',True)

add = ((ip,port1))
add2 = ((ip,port2))
redis_conn = redis.Redis(ip)
import threading
lock = threading.Lock()

connre = redis.Redis(ip)

def send(a,m=1):
    if m==2:
        ss = '%s#%s#xx'%(a)
    
    elif m==22:
        ss = '%s#%s#abs'%(a)
        
    elif m==23:
        ss = '%s#%s#abs3'%(a)

    elif m==24:
        ss = '%s#%s#abs'%(a)        
        
    elif m==3:
        ss = str(a)
        
    elif m==1:    
        if not is_pressed:
            i,j,pos = a
            ss = '%s#%s'%pos
        else:     
            ss = '4#a#a#a'
            for i in range(0,10):
                if '#%s#'%i in a:
                    ss = '%s#a#a#a'%i            
    elif m==4:
        ss = a
            
    try:
        with lock:
            redis_conn.rpush(str(port1)+"_2",sec+ss)
            print(ss,time.time())
    except Exception as e:
        print(e)
        try:
            global redis_conn
            redis_conn = redis.Redis(ip)
        except Exception as e:
            print('ex2',e)
        


last_xy = None
last_move_send_time = 0
last_move_send_time2 = 0
total_x = 0
total_y = 0
add_x = True
pass_scroll = False
min_gap = 0.05
total_x2 = 0
total_y2 = 0
last_right_click_time = 0
right_press_time = 0
move_task = None


def on_scroll(x, y, dx, dy):
    global last_move_send_time,total_x,total_y
    print(x,y,dx,dy,time.time())
    if pass_scroll:
        s = '%s#%s'%(dx,dy)+'#'*7
        send(s,4)            
        return
    
    if add_x:
        total_x += dy
    else:
        total_y += dy
    if time.time()-last_move_send_time<min_gap:
        return
    s = '%s#%s'%(-total_x,-total_y)+'#'*5
    total_y = total_x=0
    last_move_send_time = time.time()
    send(s,4)

def on_click_2(x, y, button, pressed):
    if not pressed:
        return
    if 'midd' in str(button):
        send('#'*27,4)

    if 'right' not in str(button):
        if left_right_switch:
            send('#'*28,4)  
        else:
            send('#'*7,4)
        return    
    if left_right_switch:
        send('#'*7,4)
    else:        
        send('#'*28,4)  
    global pass_scroll,add_x
    pass_scroll = True
    add_x = not add_x    
    
def on_click(x, y, button, pressed):
    print(x, y, button, pressed)
    print(str(button))
    if right_click_gear:
        return on_click_2(x, y, button, pressed)    
    global last_right_click_time,pass_scroll,add_x,right_press_time        
    if pressed:
        if 'midd' in str(button):
            send('#'*27,4)
            return        
        if 'right' not in str(button):
            send('#'*7,4)
            return    
        send('#'*9,4)        
        right_press_time = time.time()
        return
    send('#'*10,4)            
    if time.time()-right_press_time>0.3:
        return
    
    if time.time()- last_right_click_time<0.3:
        pass_scroll = True
        add_x = not add_x
        return
    last_right_click_time = time.time()
    if pass_scroll  :
        pass_scroll = False
        add_x = True
        return    
    add_x = not add_x
    

remains_x = 0
remains_y = 0

def get_scale(dx,dy):
    global remains_x,remains_y
    dx = remains_x+dx*scale
    dy =remains_y+dy*scale
    x,y = dx,dy
    if not scale_float:
        x = round(dx)
        y = round(dy)
    remains_x = dx-x
    remains_y = dy-y
    return x,y

move_pos = [-1,-1]

def on_move(dx,dy):
    global last_xy,last_move_send_time2,total_x2,total_y2,add_x,move_pos
    add_x = True                
    dx,dy = get_scale(dx, dy)
    
    if time.time()-last_move_send_time2<min_gap:
        total_x2 += dx
        total_y2 += dy                
        return
    
    ax = total_x2 +dx
    ay = total_y2 +dy            
    last_move_send_time2 = time.time()
    s = '%s#%s'%(ax,ay)+'####'
    if ax != 0 or ay !=0 :
        send(s,4)
    total_x2=total_y2=0

def on_move_t_fun():
    import struct
    with open("/dev/input/mice", mode="rb") as f:
        while True:
            button, x, y = struct.unpack('Bbb', f.read(3))
            on_move(x,-y)
        
on_move_t = threading.Thread(target=on_move_t_fun)
on_move_t.setDaemon(True)
on_move_t.start()

def back_thr():
    global last_move_send_time,last_move_send_time2,total_x,total_y,total_x2,total_y2
    while True:
        time.sleep(0.005)        
            
        if time.time()-last_move_send_time<min_gap:                    
            if total_y !=0 or total_x!=0:
                s = '%s#%s'%(-total_x,-total_y)+'#####'
                total_y = total_x=0
                last_move_send_time2 = time.time()
                send(s,4)
        if time.time()-last_move_send_time2<min_gap:                    
            if total_x2!=0 or total_y2!=0:
                last_move_send_time2 = time.time()
                s = '%s#%s'%(total_x2,total_y2)+'####'
                send(s,4)
                total_x2=total_y2=0
            
import threading
t = threading.Thread(target=back_thr)
t.setDaemon(True)
t.start()
mouse_listener = mouse.Listener(
        on_click=on_click,    
on_scroll=on_scroll)
mouse_listener.start()

class my(QMainWindow):
    def __init__(self):
        super().__init__()         
        self.show()       
a = QApplication([])   
w = my()
a.exec_()
